<html>
<head><meta charset="utf-8"><title>Status of NRVO-like optimizations · t-compiler/wg-mir-opt · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/index.html">t-compiler/wg-mir-opt</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html">Status of NRVO-like optimizations</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="194615813"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194615813" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194615813">(Apr 19 2020 at 20:09)</a>:</h4>
<p><span class="user-mention" data-user-id="211727">@Jonas Schievink</span> <span class="user-mention" data-user-id="119009">@eddyb</span> I was excited to see some recent movement towards copy propagation into the return place in <a href="https://github.com/rust-lang/rust/issues/71003" title="https://github.com/rust-lang/rust/issues/71003">#71003</a>, but that PR seems to have pretty poor worst-case performance and is now closed. Is the worst-case performance of the MIR transformation the only blocker for this class of optimizations? I saw that there are also some outstanding questions around MIR semantics now that the return place can be written to even if the function eventually unwinds, but I think these can be resolved independently?</p>



<a name="194615882"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194615882" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194615882">(Apr 19 2020 at 20:11)</a>:</h4>
<p><span class="user-mention" data-user-id="119009">@eddyb</span> also cited implementation complexity as a concern (which would arise if we tried to make this optimization fast enough), but I think it wouldn't be much more complicated than the generator transform, which does similar things.</p>



<a name="194615937"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194615937" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194615937">(Apr 19 2020 at 20:12)</a>:</h4>
<p>The MIR semantics issue is mostly resolvable independently, but I did need to modify const eval to avoid ICEs, which is in <a href="https://github.com/rust-lang/rust/issues/71005" title="https://github.com/rust-lang/rust/issues/71005">#71005</a></p>



<a name="194616042"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194616042" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194616042">(Apr 19 2020 at 20:15)</a>:</h4>
<p>One thing I wanted to play with is a borrow-aware liveness analysis, which is also used by the generator transform, and your dataflow framework changes to support backwards dataflow would help making that simpler, so I'm looking forward to that</p>



<a name="194616126"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194616126" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194616126">(Apr 19 2020 at 20:17)</a>:</h4>
<p>Yeah, that was one of my motivations. I'll try to push a bit harder to get that reviewed so you can make use of it. Lemme know if I can assist in other ways. I want to read through <code>dag_nrvo.rs</code> so I can be more helpful in this area.</p>



<a name="194616130"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194616130" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194616130">(Apr 19 2020 at 20:17)</a>:</h4>
<p>Thanks for writing the module summary BTW</p>



<a name="194616169"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194616169" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194616169">(Apr 19 2020 at 20:18)</a>:</h4>
<p>Awesome, thanks!</p>



<a name="194747960"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194747960" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194747960">(Apr 21 2020 at 00:07)</a>:</h4>
<p>I read through your PR today. It was much more like  <a href="https://github.com/rust-lang/rust/issues/47954" title="https://github.com/rust-lang/rust/issues/47954">#47954</a> than I expected, basically a robust, global copy propagator. This is cool, but there must be a simpler approach to the NRVO specifically (as opposed to global copy propagation in general) that will work for most users.</p>



<a name="194748322"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194748322" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194748322">(Apr 21 2020 at 00:12)</a>:</h4>
<p>I'm going to try to come up with a more "bottom-up" approach to the NRVO; one that tries to propagate only the small subset of copies that assign to <code>_0</code> and reach a <code>Return</code>. I'd be happy to have a discussion partner if you think this approach might have merit, but it might be more fruitful to spend time optimizing your existing approach if you think you're close.</p>



<a name="194749590"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194749590" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194749590">(Apr 21 2020 at 00:31)</a>:</h4>
<p>To elaborate, I don't care so much about propagating long chains of copies all the way into the return place. I expect that most functions that would benefit from NRVO look like the one in <a href="https://github.com/rust-lang/rust/issues/62446" title="https://github.com/rust-lang/rust/issues/62446">#62446</a>, where a large value is assigned to a local, then that value is mutated in place before it is returned.</p>



<a name="194749832"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194749832" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194749832">(Apr 21 2020 at 00:34)</a>:</h4>
<p>So I'm thinking that the first step is computing the set of reaching definitions of the return place that are live at each <code>Return</code> terminator in the MIR. This can be done robustly with dataflow, or we can just traverse the predecessor graph and abort if we find a basic block with more than two predecessors before finding a copy/move into the return place (<code>_0 = _1</code>).</p>



<a name="194749911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194749911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194749911">(Apr 21 2020 at 00:36)</a>:</h4>
<p>In the simplest case, we will have MIR like:</p>
<div class="codehilite"><pre><span></span><span class="n">_1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="mi">128</span><span class="p">];</span><span class="w"></span>
<span class="n">_1</span><span class="p">[</span><span class="n">_2</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w">   </span><span class="c1">// Mutate `_1` in place</span>
<span class="n">_0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_1</span><span class="p">;</span><span class="w"></span>
<span class="k">return</span><span class="p">;</span><span class="w"></span>
</pre></div>



<a name="194749979"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194749979" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194749979">(Apr 21 2020 at 00:37)</a>:</h4>
<p>I like to think of a <code>return</code> as an implicit "use" of <code>_0</code>. Writing that explicitly, we get:</p>
<div class="codehilite"><pre><span></span><span class="n">_1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="mi">128</span><span class="p">];</span><span class="w"></span>
<span class="c1">// Mutate `_1` in place</span>
<span class="n">_0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_1</span><span class="p">;</span><span class="w"></span>
<span class="k">return</span><span class="w"> </span><span class="n">_0</span><span class="p">;</span><span class="w"></span>
</pre></div>



<a name="194750191"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194750191" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194750191">(Apr 21 2020 at 00:40)</a>:</h4>
<p>Those last two statements are the canonical form for copy propagation. Then the question is whether it's safe to rename <code>_1</code> to <code>_0</code> to eliminate the copy.</p>



<a name="194750394"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194750394" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194750394">(Apr 21 2020 at 00:44)</a>:</h4>
<p>In what I expect is the common case, all return statements will have a single reaching definition of the return place , all of which are a copy of the same local. In this case, you could pretend that <code>return</code> takes an arbitrary local and do the transformation the other way at all return terminators.</p>
<div class="codehilite"><pre><span></span><span class="n">_1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="mi">128</span><span class="p">];</span><span class="w"></span>
<span class="c1">// _1 = _1; // removed</span>
<span class="k">return</span><span class="w"> </span><span class="n">_1</span><span class="w"></span>
</pre></div>



<a name="194750589"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194750589" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194750589">(Apr 21 2020 at 00:47)</a>:</h4>
<p>At that point, you can simply swap the names for <code>_0</code> and <code>_1</code>, although I believe there will be no more uses of <code>_0</code> remaining due to the way MIR is currently built.</p>



<a name="194789092"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194789092" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194789092">(Apr 21 2020 at 11:30)</a>:</h4>
<p>I think it can definitely be helpful to explore simpler approaches, yeah. My approach tried to simplify <a href="https://github.com/rust-lang/rust/issues/47954" title="https://github.com/rust-lang/rust/issues/47954">#47954</a> by only handling acyclic CFGs, which gets rid of all the complexity related to computing conflict matrices. The approach with reaching definitions sounds plausible, but it's hard for me to judge soundness of this approach (even my simplified NRVO pass needed a lot of iteration to work well, during which I've found some soundness bugs in the original approach as well).</p>



<a name="194791992"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194791992" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194791992">(Apr 21 2020 at 12:04)</a>:</h4>
<p>I don't feel like it's a good idea to jump straight to ad-hoc approximations with no obvious relation to the soundness conditions already identified. Even in <a href="https://github.com/rust-lang/rust/issues/71003" title="https://github.com/rust-lang/rust/issues/71003">#71003</a> as it is, the part that really killed performance (according to comments there) is the particular way in which the "live ranges do not overlap" check is converted into a potentially-whole-CFG traversal for every single candidate. I don't know why this is done in the first place, instead of "just" (devil is in the details, of course) computing a representation of the live range of every relevant place once and then doing pairwise overlap checks on these representations. This really ought to be fast enough with established techniques -- generator layout in rustc and stack coloring in LLVM use liveness information in very similar ways and they're plenty fast. Apart from that, NRVO may still be too slow e.g. because too many candidate pairs are generated (only trying to unify locals with <code>_0</code>, not arbitrary pairs of locals, would help with that). But currently I get the impression that the immediate problem isn't that the previous implementations weren't "simple" or approximate enough, but that they used approximations that aren't actually faster than "the proper way".</p>



<a name="194822854"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194822854" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194822854">(Apr 21 2020 at 15:54)</a>:</h4>
<p><span class="user-mention" data-user-id="124289">@Hanna Kruppe</span> Noted. My concern was that, because NRVO is not useful in most cases, using a better-optimized global copy propagation pass to achieve it may cause too large a regression in compile time to ultimately be worth it. I think it's valuable to explore alternatives, since propagating copies into the return place specifically should have a greater benefit than doing the same for locals residing within our stack frame.</p>



<a name="194825408"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194825408" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194825408">(Apr 21 2020 at 16:10)</a>:</h4>
<p>I share that concern and actually suggested the same restriction on discord a few days ago. Besides compile time, I also believe merging locals too eagerly could have negative effects on some LLVM optimizations (one reason why stack coloring is traditionally done very late). I was only objecting to starting by fiddling further with how we check if the optimization is legal, I see a risk of losing sight of what (and why) is actually approximated and zooming in on presumed optimizations that may be unnecessary if we took a step back first.</p>



<a name="194826366"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194826366" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194826366">(Apr 21 2020 at 16:18)</a>:</h4>
<p>That's fair. I'll put my energy into ensuring the soundness of the current approach while extending it to borrowed locals. I suspect that most functions that would benefit from NRVO borrow the local they ultimately return at some point. See the example in <del>#62466</del> <a href="https://github.com/rust-lang/rust/issues/62446" title="https://github.com/rust-lang/rust/issues/62446">#62446</a>.</p>



<a name="194831877"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194831877" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194831877">(Apr 21 2020 at 17:00)</a>:</h4>
<p>Did you mean to link a different issue= <a href="https://github.com/rust-lang/rust/issues/62466" title="https://github.com/rust-lang/rust/issues/62466">#62466</a> is about trait impls for tuples with &gt;12 elements.</p>



<a name="194833036"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194833036" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194833036">(Apr 21 2020 at 17:09)</a>:</h4>
<p>Whoops, yes <a href="https://github.com/rust-lang/rust/issues/62446" title="https://github.com/rust-lang/rust/issues/62446">#62446</a></p>



<a name="194862160"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194862160" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194862160">(Apr 21 2020 at 21:11)</a>:</h4>
<p>I'm trying put a finger on why I'm having a hard time coming up with the proper set of restrictions on the general case. The canonical example for copy propagation looks something like:</p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">foo</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">B</span><span class="p">;</span><span class="w">    </span><span class="c1">// Copy</span>

<span class="w">    </span><span class="c1">// No intervening definitions of A or B</span>

<span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">A</span><span class="p">;</span><span class="w"> </span><span class="c1">// This use of A can safely be replaced with B</span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>Note that while in this example, the use of <code>A</code> is a <code>return</code> statement, it could be any kind of use, e.g. <code>let C = A</code>.</p>



<a name="194862471"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194862471" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194862471">(Apr 21 2020 at 21:13)</a>:</h4>
<p>Is the necessary restriction more than "A and B are never live at the same time"?</p>



<a name="194862534"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194862534" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194862534">(Apr 21 2020 at 21:14)</a>:</h4>
<p>(plus some MIR-specific oddities, of course)</p>



<a name="194862633"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194862633" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194862633">(Apr 21 2020 at 21:15)</a>:</h4>
<p>What's somewhat unique about NRVO on the MIR is that the name of the local that is returned is always the same. Previous attempts are actually trying to solve a slightly different problem:</p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">foo</span><span class="p">()</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"> </span><span class="c1">// Can B be replaced with A?</span>

<span class="w">    </span><span class="c1">// What are the restrictions on statements between the initial definition of B and the copy?</span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">B</span><span class="p">;</span><span class="w">    </span><span class="c1">// Copy</span>

<span class="w">     </span><span class="c1">// What about between the copy and the use of A?</span>

<span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">A</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="194862838"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194862838" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194862838">(Apr 21 2020 at 21:16)</a>:</h4>
<p>So that depends on your definition of liveness. If <code>B</code> becomes "live" as soon as it is borrowed, then that's a deal-breaker</p>



<a name="194862923"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194862923" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194862923">(Apr 21 2020 at 21:17)</a>:</h4>
<p>It would, yes</p>



<a name="194862997"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194862997" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194862997">(Apr 21 2020 at 21:17)</a>:</h4>
<p>I want to look at "indirect definitions" (e.g. <code>*p = 42</code> or arbitrary function calls) and consider them a "def" of a given local in the liveness analysis here <em>only if</em> a (mutable) borrow to that local could exist at that point</p>



<a name="194863065"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863065" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863065">(Apr 21 2020 at 21:18)</a>:</h4>
<p>Yeah, that's what the original attempt tried to do</p>



<a name="194863122"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863122" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863122">(Apr 21 2020 at 21:19)</a>:</h4>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">foo</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"></span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">B</span><span class="p">;</span><span class="w"> </span><span class="c1">// B becomes borrowed here</span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">B</span><span class="p">;</span><span class="w"></span>

<span class="w">    </span><span class="c1">// But there is no intervening definition, direct or indirect, here</span>
<span class="w">    </span><span class="c1">// foo();</span>

<span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">A</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="194863226"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863226" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863226">(Apr 21 2020 at 21:20)</a>:</h4>
<p>But wouldn't you have to give up as soon as the borrow escapes the local stack frame?</p>



<a name="194863241"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863241" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863241">(Apr 21 2020 at 21:20)</a>:</h4>
<p>Right, so it's quite clear to me how that applies to the first example above. It's less clear how it applies to the second example.</p>



<a name="194863296"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863296" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863296">(Apr 21 2020 at 21:20)</a>:</h4>
<p>Our locals only exist as long as our stack frame is live</p>



<a name="194863332"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863332" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863332">(Apr 21 2020 at 21:21)</a>:</h4>
<p>Do you mean escapes into callees? Yes.</p>



<a name="194863387"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863387" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863387">(Apr 21 2020 at 21:22)</a>:</h4>
<p>Yeah. But if the reference is passed via a function call you wouldn't just have a single use, you'd potentially have continued uses (due to threads) until the local is deallocated.</p>



<a name="194863418"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863418" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863418">(Apr 21 2020 at 21:22)</a>:</h4>
<p>Or moved out of, but that isn't currently used by optimizations</p>



<a name="194863466"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863466" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863466">(Apr 21 2020 at 21:23)</a>:</h4>
<p>That's why we have to treat any function call as an indirect definition. As soon as we have a function call between the copy and the use, we can't do copy propagation unless we can prove that the local is not (mutably) borrowed.</p>



<a name="194863639"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863639" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863639">(Apr 21 2020 at 21:25)</a>:</h4>
<p>Ah</p>



<a name="194863838"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863838" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863838">(Apr 21 2020 at 21:27)</a>:</h4>
<p>I guess my question is: Is the same condition that is necessary to replace the use of <code>A</code> with one of <code>B</code> in the first example sufficient to justify replacing the definition of <code>B</code> with one of <code>A</code> in the second?</p>



<a name="194863934"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863934" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863934">(Apr 21 2020 at 21:28)</a>:</h4>
<p>The condition being: "no intervening definitions of <code>A</code> or <code>B</code> between the copy and the use of <code>A</code>"</p>



<a name="194863965"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194863965" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194863965">(Apr 21 2020 at 21:28)</a>:</h4>
<p>(I'm currently trying to find a counter-example)</p>



<a name="194865600"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194865600" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194865600">(Apr 21 2020 at 21:46)</a>:</h4>
<p>Obviously, as soon as you have other uses of <code>B</code>, you would need to rename these as well. I'm not sure what conditions that would make this renaming legal.</p>



<a name="194865722"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194865722" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194865722">(Apr 21 2020 at 21:47)</a>:</h4>
<p>Your mental model, checking whether live ranges overlap, works quite nicely because then there can be no problems coalescing two locals into one.</p>



<a name="194865839"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194865839" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194865839">(Apr 21 2020 at 21:48)</a>:</h4>
<p>So probably I need to adopt that one.</p>



<a name="194865853"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194865853" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194865853">(Apr 21 2020 at 21:48)</a>:</h4>
<p>Hmm, yeah, that's why we've used the model based on live ranges of the variables so far. Is there a reason you want to use a different condition?</p>



<a name="194865877"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194865877" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194865877">(Apr 21 2020 at 21:48)</a>:</h4>
<p>("that" being "it seems pretty clearly sound")</p>



<a name="194865916"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194865916" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194865916">(Apr 21 2020 at 21:49)</a>:</h4>
<p>I'm thinking it's not as precise in the presence of <em>immutable</em> borrows.</p>



<a name="194866091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194866091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194866091">(Apr 21 2020 at 21:50)</a>:</h4>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">foo</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">B</span><span class="p">;</span><span class="w"> </span><span class="c1">// B becomes borrowed here</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">B</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">foo</span><span class="p">(</span><span class="n">p</span><span class="p">);</span><span class="w"> </span><span class="c1">// B is &quot;used&quot; here</span>
<span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">A</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="194866268"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194866268" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194866268">(Apr 21 2020 at 21:52)</a>:</h4>
<p>Replacing the use of <code>A</code> with one of <code>B</code> is still sound in this case. Despite the fact that the live ranges of <code>A</code> and <code>B</code> overlap.</p>



<a name="194866301"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194866301" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194866301">(Apr 21 2020 at 21:52)</a>:</h4>
<p>(again with most definitions of "liveness")</p>



<a name="194866500"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194866500" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194866500">(Apr 21 2020 at 21:54)</a>:</h4>
<p>That's why I think the "nonoverlapping live ranges" mental model is not strictly better than the "no intervening definitions between copy and use" mental model</p>



<a name="194866554"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194866554" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194866554">(Apr 21 2020 at 21:55)</a>:</h4>
<p>Although one may be better in practice.</p>



<a name="194866988"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194866988" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194866988">(Apr 21 2020 at 21:58)</a>:</h4>
<p>That's true, but "no intervening definitions" does not seem sufficient for soundness due to unrelated uses of A and B in other places in the function</p>



<a name="194867174"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194867174" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194867174">(Apr 21 2020 at 22:00)</a>:</h4>
<p>The no intervening definitions approach is perfectly sound, but it only considers a single use of a variable at a time.</p>



<a name="194867237"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194867237" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194867237">(Apr 21 2020 at 22:01)</a>:</h4>
<p>Whereas "nonoverlapping live ranges" considers all uses/definitions of a pair of variables.</p>



<a name="194867649"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194867649" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194867649">(Apr 21 2020 at 22:04)</a>:</h4>
<p>So what I've been considering is a sort of two-phase approach. First is traditional global copy propagation, where we consider <code>return</code> a "use" of the local <code>_0</code> and allow a global copy propagation pass to replace those uses with other locals. Then we visit all possible return places to see which local is most commonly used as the return value, rename that local to <code>_0</code> and then insert copies to <code>_0</code> for all return statements that <em>don't</em> use the most common local.</p>



<a name="194871772"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/194871772" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#194871772">(Apr 21 2020 at 22:53)</a>:</h4>
<p>(I call this "traditional" because it's in <a href="https://www.amazon.com/Advanced-Compiler-Design-Implementation-Muchnick/dp/1558603204" title="https://www.amazon.com/Advanced-Compiler-Design-Implementation-Muchnick/dp/1558603204">https://www.amazon.com/Advanced-Compiler-Design-Implementation-Muchnick/dp/1558603204</a>)</p>



<a name="195378051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378051">(Apr 27 2020 at 06:44)</a>:</h4>
<p>argh this is a long thread</p>



<a name="195378201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378201">(Apr 27 2020 at 06:46)</a>:</h4>
<blockquote>
<p>but I think it wouldn't be much more complicated than the generator transform, which does similar things.</p>
</blockquote>
<p>I just wanted to point that the generator transform is simpler because it doesn't care about accesses, only storage live ranges, and fundamentally it overlaps <em>unrelated</em> locals whereas NRVO needs to overlap locals with <em>transfers</em> between them (which requires they both be live at the same time)</p>



<a name="195378227"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378227" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378227">(Apr 27 2020 at 06:47)</a>:</h4>
<p>also every time you unify two locals, the conflict matrix needs to be updated to account for "shallow transitivity"</p>



<a name="195378324"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378324" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378324">(Apr 27 2020 at 06:49)</a>:</h4>
<p>also, NRVO and copy propagation aren't the same, they're more like...duals</p>



<a name="195378387"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378387" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378387">(Apr 27 2020 at 06:50)</a>:</h4>
<p>what is usually called "copy propagation" is "(forward) source propagation" while NRVO in the sense that I use it in is "(backwards) destination propagation"</p>



<a name="195378507"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378507" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378507">(Apr 27 2020 at 06:53)</a>:</h4>
<p>and unifying locals is not exactly "propagation", i.e. it's global and the resulting MIR has one less local, whereas "destination propagation" could be understood to be more local and skip a copy without getting rid of the intermediary local from <em>other</em> places in the MIR</p>



<a name="195378621"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378621" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378621">(Apr 27 2020 at 06:55)</a>:</h4>
<p>I think forward source propagation is harder in some respects, because you have to check that you can move an <code>Rvalue</code> all the way down to an use of a local</p>



<a name="195378741"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378741" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378741">(Apr 27 2020 at 06:57)</a>:</h4>
<p>so it's kind of like the conflict check of replacing <code>b = a</code> by unifying <code>a</code> and <code>b</code> when their live ranges don't overlap, except for swapping two statements</p>



<a name="195378833"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378833" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378833">(Apr 27 2020 at 06:58)</a>:</h4>
<p>but in that sense, <code>b = a</code> is a "local" check (after the live ranges have been computed), whereas the source propagation requires you to effectively swap statements the entire path between def and use</p>



<a name="195378846"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378846" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378846">(Apr 27 2020 at 06:59)</a>:</h4>
<p>you wouldn't literally implement it as such, but there's more to check overall IIUC</p>



<a name="195378895"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378895" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378895">(Apr 27 2020 at 07:00)</a>:</h4>
<p>for SSA-like locals though, you can do a better job at propagating them into uses, as long as the original is still live</p>



<a name="195378952"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195378952" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195378952">(Apr 27 2020 at 07:00)</a>:</h4>
<p>IMO this is most useful (ignoring consts which have their own propagation) for arguments</p>



<a name="195379023"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195379023" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195379023">(Apr 27 2020 at 07:01)</a>:</h4>
<p>and I suppose non-<code>Use</code> <code>Rvalue</code>s if you want to do that</p>



<a name="195379134"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195379134" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195379134">(Apr 27 2020 at 07:03)</a>:</h4>
<p>MIR statements of the form <code>local = local;</code> can be optimized by either unifying the locals ("NRVO") or propagating the RHS to uses of the LHS, and you can't do the former if the RHS is an argument</p>



<a name="195379145"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195379145" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195379145">(Apr 27 2020 at 07:03)</a>:</h4>
<p>or, wait, you can?! did I get confused at some point in the past?</p>



<a name="195379235"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195379235" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195379235">(Apr 27 2020 at 07:04)</a>:</h4>
<p>just like you can only unify <code>_0</code> with a local by renaming <em>that</em> local to <code>_0</code>, not the other way around, you can unify arguments with other locals by renaming those locals to the argument</p>



<a name="195379244"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195379244" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195379244">(Apr 27 2020 at 07:04)</a>:</h4>
<p>the difference being that <code>_0</code> is usually a destination and arguments are usually a source</p>



<a name="195379344"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195379344" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195379344">(Apr 27 2020 at 07:06)</a>:</h4>
<p>so IOW, copyprop aka "source propagation" is most useful when you have non-<code>Use</code> <code>Rvalue</code>s, if I'm not mistaken</p>



<a name="195379358"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195379358" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195379358">(Apr 27 2020 at 07:06)</a>:</h4>
<p>or I guess places with projections</p>



<a name="195379541"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195379541" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195379541">(Apr 27 2020 at 07:09)</a>:</h4>
<p><span class="user-mention" data-user-id="118594">@ecstatic-morse</span> also, MIR working with <em>places</em> rather than <em>values</em> means a bunch of textbook stuff (e.g. SSA) doesn't apply as cleanly, and some of the tradeoffs are different too</p>



<a name="195379626"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195379626" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195379626">(Apr 27 2020 at 07:10)</a>:</h4>
<p>I much prefer approaches like my "local unification" in how it completely eliminates reasoning about "code motion"</p>



<a name="195443685"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/195443685" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#195443685">(Apr 27 2020 at 16:42)</a>:</h4>
<p><span class="user-mention silent" data-user-id="118594">ecstatic-morse</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/194822854" title="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/194822854">said</a>:</p>
<blockquote>
<p><strong>Hanna Kruppe</strong> Noted. My concern was that, because NRVO is not useful in most cases, using a better-optimized global copy propagation pass to achieve it may cause too large a regression in compile time to ultimately be worth it. I think it's valuable to explore alternatives, since propagating copies into the return place specifically should have a greater benefit than doing the same for locals residing within our stack frame.</p>
</blockquote>
<p>Maybe it is possible to compute a quick score/heuristic that tells us how likely it is that NRVO is going to be useful. That way we don't run it for most of the time, but when we do, it gives big perf wins. If that makes sense?</p>



<a name="196713483"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196713483" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196713483">(May 07 2020 at 00:09)</a>:</h4>
<p>One thing that might become a performance issue is that we need to know about liveness and "borrowed-ness" of all locals at every single statement to build the conflict matrix, but liveness is a backwards analysis, while "borrowed-ness" (and <code>MaybeInitializedLocals</code>) are forward analyses, so for at least one analysis we will have <code>O(n²)</code> visiting of all statements, at least with the current cursor API.</p>
<p>(Generators don't have this problem because they only use forward analyses to build their conflict matrix – liveness doesn't factor into which locals may or may not overlap in their state)</p>
<p>This is likely to be an issue at least for the <code>tuple-stress</code> benchmark, which has 1 basic block with 458745 statements.</p>
<p><span class="user-mention" data-user-id="118594">@ecstatic-morse</span> you might have some ideas for how to make the cursor API more performant for cases like this.</p>



<a name="196713620"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196713620" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196713620">(May 07 2020 at 00:11)</a>:</h4>
<p>Can you go once backward through the basic block and once forward?</p>



<a name="196713710"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196713710" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196713710">(May 07 2020 at 00:12)</a>:</h4>
<p>Oh, that's right. We just <code>|</code> the bits in the conflict matrix. Well that was easy.</p>



<a name="196713741"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196713741" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196713741">(May 07 2020 at 00:13)</a>:</h4>
<p>NP lemme know if anything else comes up.</p>



<a name="196723097"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196723097" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196723097">(May 07 2020 at 03:10)</a>:</h4>
<p>Good job you guys! :D</p>



<a name="196948490"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196948490" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196948490">(May 08 2020 at 20:45)</a>:</h4>
<p>Heh, apparently the liveness analysis does not consider <code>_0</code> live, ever. Maybe the MIR visitor code should treat <code>return</code> like a use of <code>_0</code> to fix this, and potentially handling in other passes?</p>



<a name="196948724"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196948724" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196948724">(May 08 2020 at 20:47)</a>:</h4>
<p>Oh, no, that's not true either, <code>_0</code> <em>is</em> live, but only at the <em>start</em> of the function? But it doesn't contain any value there...</p>



<a name="196949104"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196949104" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196949104">(May 08 2020 at 20:50)</a>:</h4>
<div class="codehilite"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">BigTest</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">arr</span>: <span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">128</span><span class="p">]</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="n">BigTest</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">new</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nc">BigTest</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">BigTest</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">arr</span>: <span class="p">[</span><span class="mi">123</span><span class="p">;</span><span class="w"> </span><span class="mi">128</span><span class="p">],</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>


<p>yields:</p>
<div class="codehilite"><pre><span></span><code><span class="k">fn</span> <span class="o">&lt;</span><span class="k">impl</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">nrvo</span><span class="p">.</span><span class="n">rs</span>:<span class="mi">9</span>:<span class="mi">1</span>: <span class="mi">15</span>:<span class="mi">2</span><span class="o">&gt;</span>::<span class="n">new</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nc">BigTest</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_0</span>: <span class="nc">BigTest</span><span class="p">;</span><span class="w">                 </span><span class="c1">// return place in scope 0 at nrvo.rs:10:21: 10:28</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_1</span>: <span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">128</span><span class="p">];</span><span class="w">              </span><span class="c1">// in scope 0 at nrvo.rs:12:18: 12:28</span>

<span class="w">    </span><span class="c1">// init: []</span>
<span class="w">    </span><span class="c1">// live: [_0]</span>
<span class="w">    </span><span class="n">bb0</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="c1">// init: []</span>
<span class="w">        </span><span class="c1">// live: [_0]</span>
<span class="w">        </span><span class="n">StorageLive</span><span class="p">(</span><span class="n">_1</span><span class="p">);</span><span class="w">                 </span><span class="c1">// scope 0 at nrvo.rs:12:18: 12:28</span>
<span class="w">        </span><span class="c1">// init: []</span>
<span class="w">        </span><span class="c1">// live: [_0, _1]</span>
<span class="w">        </span><span class="n">_1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="k">const</span><span class="w"> </span><span class="mi">123</span><span class="k">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">128</span><span class="p">];</span><span class="w">        </span><span class="c1">// scope 0 at nrvo.rs:12:18: 12:28</span>
<span class="w">                                         </span><span class="c1">// ty::Const</span>
<span class="w">                                         </span><span class="c1">// + ty: u32</span>
<span class="w">                                         </span><span class="c1">// + val: Value(Scalar(0x0000007b))</span>
<span class="w">                                         </span><span class="c1">// mir::Constant</span>
<span class="w">                                         </span><span class="c1">// + span: nrvo.rs:12:19: 12:22</span>
<span class="w">                                         </span><span class="c1">// + literal: Const { ty: u32, val: Value(Scalar(0x0000007b)) }</span>
<span class="w">        </span><span class="c1">// init: [_1]</span>
<span class="w">        </span><span class="c1">// live: []</span>
<span class="w">        </span><span class="p">(</span><span class="n">_0</span><span class="p">.</span><span class="mi">0</span>: <span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">128</span><span class="p">])</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="n">_1</span><span class="p">;</span><span class="w">    </span><span class="c1">// scope 0 at nrvo.rs:11:9: 13:10</span>
<span class="w">        </span><span class="c1">// init: [_0]</span>
<span class="w">        </span><span class="c1">// live: []</span>
<span class="w">        </span><span class="n">StorageDead</span><span class="p">(</span><span class="n">_1</span><span class="p">);</span><span class="w">                 </span><span class="c1">// scope 0 at nrvo.rs:13:9: 13:10</span>
<span class="w">        </span><span class="c1">// init: [_0]</span>
<span class="w">        </span><span class="c1">// live: []</span>
<span class="w">        </span><span class="k">return</span><span class="p">;</span><span class="w">                          </span><span class="c1">// scope 0 at nrvo.rs:14:6: 14:6</span>
<span class="w">        </span><span class="c1">// init: [_0]</span>
<span class="w">        </span><span class="c1">// live: []</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="196949241"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196949241" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196949241">(May 08 2020 at 20:51)</a>:</h4>
<p>(where <code>init</code> is <code>MaybeInitializedLocals</code> and <code>live</code> is <code>MaybeLiveLocals</code>)</p>



<a name="196949600"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196949600" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196949600">(May 08 2020 at 20:55)</a>:</h4>
<p>"Maybe the MIR visitor code should treat return like a use of _0 to fix this" - I would like to see this.</p>



<a name="196949724"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196949724" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196949724">(May 08 2020 at 20:56)</a>:</h4>
<p>Isn't "live before initialized" going to be a problem for anything initialized by an aggregate rvalue, which becomes a bunch of field assignments.</p>



<a name="196949958"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196949958" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196949958">(May 08 2020 at 20:58)</a>:</h4>
<p>(my printing code was a bit broken, I've edited the output)</p>



<a name="196950066"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196950066" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196950066">(May 08 2020 at 20:59)</a>:</h4>
<p>Certainly I wouldn't expect any locals to be live at the start of bb0 in any case, that implies a use of uninitialized data if I understand liveness correctly</p>



<a name="196950160"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196950160" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196950160">(May 08 2020 at 21:00)</a>:</h4>
<p>Ah, well except arguments of course</p>



<a name="196950701"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196950701" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196950701">(May 08 2020 at 21:06)</a>:</h4>
<p>"Live and initialized" is generally what's needed. Borrowck used to have an issue where uninitialized variables were considered to be live because there was a <code>Drop</code> of them along some unwind path (which drop elaboration would fix). Here liveness believes that assigning to <code>_0.0</code> is a use, even though it isn't (this behavior is correct for borrowck).</p>



<a name="196952615"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196952615" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196952615">(May 08 2020 at 21:27)</a>:</h4>
<p>Oof, yeah, the interaction with aggregates is bad...</p>



<a name="196953051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196953051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196953051">(May 08 2020 at 21:32)</a>:</h4>
<p>This comes from marking <code>MutatingUseContext::Projection</code> as a "use". According to the docs, that context is used for both <code>&amp;mut x.y</code> (which is indeed a use of <code>x</code>) and <code>x.y = ...</code> (which is not a use of <code>x</code> but is also not a def of the entirety of <code>x</code>). Looks like we'll need to stop relying on <code>PlaceContext</code> for MIR liveness.</p>



<a name="196953128"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196953128" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196953128">(May 08 2020 at 21:33)</a>:</h4>
<p>Yeah, it kinda does makes sense</p>



<a name="196953197"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196953197" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196953197">(May 08 2020 at 21:34)</a>:</h4>
<p>Somehow I'm also getting different liveness after a block's terminator when compared to after the block itself, in the function above...</p>



<a name="196953210"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196953210" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196953210">(May 08 2020 at 21:34)</a>:</h4>
<p>But yeah, we need to handle <code>return</code> properly. That's a bug and maybe caused the unexpected changes in <a href="https://github.com/rust-lang/rust/issues/71956" title="https://github.com/rust-lang/rust/issues/71956">#71956</a>?</p>



<a name="196953372"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196953372" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196953372">(May 08 2020 at 21:36)</a>:</h4>
<p>I somewhat doubt that, as I don't think <code>_0</code> can ever be live across a yield currently.</p>



<a name="196953607"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196953607" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196953607">(May 08 2020 at 21:39)</a>:</h4>
<p>I say this only because there's a mention of NRVO in the comment above  one of the generator tests whose size changed. I think it might be outdated; It seems wrong to me. <a href="https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/test/ui/generator/size-moved-locals.rs#L48-L59" title="https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/test/ui/generator/size-moved-locals.rs#L48-L59">https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/test/ui/generator/size-moved-locals.rs#L48-L59</a></p>



<a name="196953766"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196953766" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196953766">(May 08 2020 at 21:40)</a>:</h4>
<p><span class="user-mention silent" data-user-id="211727">Jonas Schievink</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/196953197" title="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/196953197">said</a>:</p>
<blockquote>
<p>Somehow I'm also getting different liveness after a block's terminator when compared to after the block itself, in the function above...</p>
</blockquote>
<p>Can you be more specific? Remember <code>seek_after_primary_effect(terminator_loc)</code> and <code>seek_to_block_end</code> are not the same for backward dataflow analyses. That's why the name of the first changed from <code>seek_after</code>.</p>



<a name="196953983"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196953983" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196953983">(May 08 2020 at 21:43)</a>:</h4>
<p>Ah, right, I've been printing the wrong dataflow state then</p>



<a name="196954223"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196954223" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196954223">(May 08 2020 at 21:46)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116118">Matthew Jasper</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/196949600" title="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/196949600">said</a>:</p>
<blockquote>
<p>"Maybe the MIR visitor code should treat return like a use of _0 to fix this" - I would like to see this.</p>
</blockquote>
<p>I also think this is a good idea.</p>



<a name="196954650"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196954650" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196954650">(May 08 2020 at 21:51)</a>:</h4>
<p>So, is this the correct way to print the dataflow state between statements?</p>
<div class="codehilite"><pre><span></span><code><span class="n">PassWhere</span>::<span class="n">BeforeLocation</span><span class="p">(</span><span class="n">loc</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">init</span><span class="p">.</span><span class="n">seek_before_primary_effect</span><span class="p">(</span><span class="n">loc</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">live</span><span class="p">.</span><span class="n">seek_after_primary_effect</span><span class="p">(</span><span class="n">loc</span><span class="p">);</span><span class="w"></span>

<span class="w">    </span><span class="n">writeln</span><span class="o">!</span><span class="p">(</span><span class="n">w</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;        // init: {:?}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">init</span><span class="p">.</span><span class="n">get</span><span class="p">())</span><span class="o">?</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">writeln</span><span class="o">!</span><span class="p">(</span><span class="n">w</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;        // live: {:?}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">live</span><span class="p">.</span><span class="n">get</span><span class="p">())</span><span class="o">?</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="n">PassWhere</span>::<span class="n">AfterTerminator</span><span class="p">(</span><span class="n">bb</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">loc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">body</span><span class="p">.</span><span class="n">terminator_loc</span><span class="p">(</span><span class="n">bb</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">init</span><span class="p">.</span><span class="n">seek_after_primary_effect</span><span class="p">(</span><span class="n">loc</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">live</span><span class="p">.</span><span class="n">seek_before_primary_effect</span><span class="p">(</span><span class="n">loc</span><span class="p">);</span><span class="w"></span>

<span class="w">    </span><span class="n">writeln</span><span class="o">!</span><span class="p">(</span><span class="n">w</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;        // init: {:?}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">init</span><span class="p">.</span><span class="n">get</span><span class="p">())</span><span class="o">?</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">writeln</span><span class="o">!</span><span class="p">(</span><span class="n">w</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;        // live: {:?}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">live</span><span class="p">.</span><span class="n">get</span><span class="p">())</span><span class="o">?</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="196954770"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196954770" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196954770">(May 08 2020 at 21:53)</a>:</h4>
<p>(it looks correct now, at least)</p>



<a name="196954833"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196954833" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196954833">(May 08 2020 at 21:54)</a>:</h4>
<p>Yes. That should give you the correct results (it's slow for liveness, but you already knew that)</p>



<a name="196958057"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196958057" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196958057">(May 08 2020 at 22:32)</a>:</h4>
<p>One issue with making <code>return</code> read from <code>_0</code> is that <code>MutVisitor</code> receives a <code>&amp;mut Local</code>, but this would be the only <code>Local</code> it cannot actually mutate.</p>



<a name="196958085"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196958085" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196958085">(May 08 2020 at 22:32)</a>:</h4>
<p>I can put an assertion in the visitor code, but maybe there's a better solution?</p>



<a name="196958122"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196958122" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196958122">(May 08 2020 at 22:33)</a>:</h4>
<p>(the assertion is needed, CopyProp started miscompiling things otherwise)</p>



<a name="196991032"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196991032" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196991032">(May 09 2020 at 13:09)</a>:</h4>
<p>Regarding the interaction of liveness with aggregates, maybe that could be fixed by making liveness act on places instead of locals?</p>



<a name="196991099"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196991099" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196991099">(May 09 2020 at 13:11)</a>:</h4>
<p>Or maybe my <code>MergeLocals</code> pass should run before the deaggregator. The generator transform already does that, interestingly. I wonder if it'd break if we run it afterwards.</p>



<a name="196991471"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/196991471" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#196991471">(May 09 2020 at 13:20)</a>:</h4>
<p><span class="user-mention silent" data-user-id="211727">Jonas Schievink</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/196991099" title="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/196991099">said</a>:</p>
<blockquote>
<p>Or maybe my <code>MergeLocals</code> pass should run before the deaggregator. The generator transform already does that, interestingly. I wonder if it'd break if we run it afterwards.</p>
</blockquote>
<p>Ah, well this doesn't work since the pass then can't propagate destinations at all</p>



<a name="197020482"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197020482" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197020482">(May 09 2020 at 23:33)</a>:</h4>
<p>I've now hit a peculiar issue where my NRVO pass apparently misoptimizes <a href="https://github.com/rust-lang/rust/blob/74bd074eefcf4915c73d1ab91bc90859664729e6/src/liballoc/str.rs#L137" title="https://github.com/rust-lang/rust/blob/74bd074eefcf4915c73d1ab91bc90859664729e6/src/liballoc/str.rs#L137"><code>join_generic_copy</code></a>, but looking at how the MIR changes, it seems that the <em>input</em> to my pass contains an <code>Operand::Copy</code> that copies from a local of type <code>&amp;mut [T]</code>, and according to the docs that is not supposed to happen. Is that correct? If so, is there any way to run a sort of sanitizer pass between each optimization that could find these issues? Maybe the MIR typecheck pass?</p>



<a name="197028326"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197028326" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197028326">(May 10 2020 at 02:45)</a>:</h4>
<p>Ohh</p>



<a name="197028327"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197028327" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197028327">(May 10 2020 at 02:45)</a>:</h4>
<p>Yes</p>



<a name="197028328"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197028328" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197028328">(May 10 2020 at 02:45)</a>:</h4>
<p>That's a good idea</p>



<a name="197028330"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197028330" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197028330">(May 10 2020 at 02:45)</a>:</h4>
<p>I mean</p>



<a name="197028331"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197028331" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197028331">(May 10 2020 at 02:45)</a>:</h4>
<p>We should never need them if the optimizations are correct</p>



<a name="197028332"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197028332" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197028332">(May 10 2020 at 02:45)</a>:</h4>
<p>Like, sound</p>



<a name="197028371"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197028371" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197028371">(May 10 2020 at 02:46)</a>:</h4>
<p>But maybe we could run that sanitizer while in testing mode</p>



<a name="197028373"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197028373" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197028373">(May 10 2020 at 02:46)</a>:</h4>
<p>Or no. Even better: we could run that sanitizer in a special mode where we basically run crater</p>



<a name="197028374"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197028374" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197028374">(May 10 2020 at 02:46)</a>:</h4>
<p>And we check that our transformations are sound</p>



<a name="197078397"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197078397" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197078397">(May 10 2020 at 21:00)</a>:</h4>
<p>This appears to be caused by the <code>&amp;*x =&gt; x</code> transform made by InstCombine</p>



<a name="197086131"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197086131" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197086131">(May 10 2020 at 23:45)</a>:</h4>
<p><del>#72093 seems to fix the issues I was seeing</del> nevermind</p>



<a name="197458625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197458625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197458625">(May 13 2020 at 18:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="211727">Jonas Schievink</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/197078397">said</a>:</p>
<blockquote>
<p>This appears to be caused by the <code>&amp;*x =&gt; x</code> transform made by InstCombine</p>
</blockquote>
<p>You might be interested in <a href="https://github.com/rust-lang/rust/issues/46420">https://github.com/rust-lang/rust/issues/46420</a></p>



<a name="197459141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197459141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197459141">(May 13 2020 at 18:51)</a>:</h4>
<p>Ah, indeed</p>



<a name="197610658"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197610658" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197610658">(May 14 2020 at 20:07)</a>:</h4>
<p>I wonder if it makes sense to create an <code>A-mir-opt-nrvo</code> label to track issues that would be fixed by this...</p>



<a name="197611093"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197611093" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Wesley Wiser <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197611093">(May 14 2020 at 20:10)</a>:</h4>
<p>I think that would be good. We have <code>A-mir-opt-inlining</code> which is similar</p>



<a name="197611579"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197611579" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197611579">(May 14 2020 at 20:14)</a>:</h4>
<p>Created one</p>



<a name="197611684"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197611684" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Wesley Wiser <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197611684">(May 14 2020 at 20:15)</a>:</h4>
<p>Looking through the tagged issues is also helpful when trying to stabilize the optimization because we can extract test cases.</p>



<a name="197612155"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197612155" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197612155">(May 14 2020 at 20:19)</a>:</h4>
<p>Yay! I find these kinds of things make writing test suites much easier.</p>



<a name="197747731"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197747731" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197747731">(May 15 2020 at 20:20)</a>:</h4>
<p>Status update: I've been hacking on dataflow-based NRVO in my spare time, but still have to work out some kinks. I'm hoping to make more progress over the weekend (and if not, next weekend).</p>



<a name="197749815"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197749815" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197749815">(May 15 2020 at 20:40)</a>:</h4>
<p>please sync with <span class="user-mention" data-user-id="119009">@eddyb</span> because they also have such a pass</p>



<a name="197749851"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197749851" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197749851">(May 15 2020 at 20:41)</a>:</h4>
<p>ehm</p>



<a name="197749862"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197749862" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197749862">(May 15 2020 at 20:41)</a>:</h4>
<p>I'm pretty sure everyone here knows about my history with NRVO?</p>



<a name="197749896"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197749896" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197749896">(May 15 2020 at 20:41)</a>:</h4>
<p>at least <span class="user-mention" data-user-id="211727">@Jonas Schievink</span> who I've talked extensively to about it</p>



<a name="197749958"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197749958" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197749958">(May 15 2020 at 20:42)</a>:</h4>
<p>yeah, <span class="user-mention" data-user-id="119009">@eddyb</span> guided me through my last attempt :)</p>



<a name="197750372"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197750372" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197750372">(May 15 2020 at 20:46)</a>:</h4>
<p>(some of the recent experiments were based on my hopes that there are simpler ways to correctly approximate the conditions for NRVO than my original attempt at it which I don't feel great about due to the complexity, although now that I've discussed it with <span class="user-mention" data-user-id="124289">@Hanna Kruppe</span> and <span class="user-mention" data-user-id="211727">@Jonas Schievink</span>, I could see ways to break it up into understandable "standard compiler concept" pieces. sadly I'm again not working on optimizations so... yeah I can't do much about it atm)</p>



<a name="197754905"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/197754905" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#197754905">(May 15 2020 at 21:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="211727">Jonas Schievink</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/197747731">said</a>:</p>
<blockquote>
<p>Status update: I've been hacking on dataflow-based NRVO in my spare time, but still have to work out some kinks. I'm hoping to make more progress over the weekend (and if not, next weekend).</p>
</blockquote>
<p><span class="user-mention" data-user-id="211727">@Jonas Schievink</span>  Let me know if you see any room for improvement within the dataflow framework. You're basically the first person using it to write new stuff, so your feedback is very useful.</p>



<a name="198586170"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198586170" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198586170">(May 24 2020 at 14:47)</a>:</h4>
<p><span class="user-mention" data-user-id="118594">@ecstatic-morse</span> So, my destination propagation pass now makes your NRVO pass fail this assertion: <a href="https://github.com/rust-lang/rust/blob/7726070fa755f660b5da3f82f46e07d9c6866f69/src/librustc_mir/transform/nrvo.rs#L206">https://github.com/rust-lang/rust/blob/7726070fa755f660b5da3f82f46e07d9c6866f69/src/librustc_mir/transform/nrvo.rs#L206</a></p>



<a name="198586208"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198586208" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198586208">(May 24 2020 at 14:48)</a>:</h4>
<p>Does your pass work when <code>_0</code> is "just another local"?</p>



<a name="198587170"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198587170" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198587170">(May 24 2020 at 15:13)</a>:</h4>
<p>You can turn it off if you're already renaming the return place</p>



<a name="198587769"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198587769" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198587769">(May 24 2020 at 15:29)</a>:</h4>
<p>That is true I guess</p>



<a name="198587817"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198587817" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198587817">(May 24 2020 at 15:30)</a>:</h4>
<p>Hmm, can NRVO create <code>Operand::Move</code> after replacement, but have the moved place still be used afterwards?</p>



<a name="198587885"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198587885" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198587885">(May 24 2020 at 15:32)</a>:</h4>
<p>Seems like yes? If it propagates this:</p>
<div class="codehilite"><pre><span></span><code>_3 = _4;
(_2.0: i32) = move _3;
(_2.1: i32) = move _4;
</code></pre></div>


<p>It can produce</p>
<div class="codehilite"><pre><span></span><code>(_2.0: i32) = move _4;
(_2.1: i32) = move _4;
</code></pre></div>


<p>Seems bad if we do want to use <code>Operand::Move</code> vs. <code>Operand::Copy</code> for optimizations. This might also be true for the existing pass.</p>



<a name="198588109"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198588109" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198588109">(May 24 2020 at 15:39)</a>:</h4>
<p>Ah nevermind, it would just produce</p>
<div class="codehilite"><pre><span></span><code>(_2.0: i32) = _4;
nop;
(_2.1: i32) = move _4;
</code></pre></div>



<a name="198595748"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198595748" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198595748">(May 24 2020 at 19:12)</a>:</h4>
<p>Oof, that's a relief</p>



<a name="198595749"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198595749" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198595749">(May 24 2020 at 19:12)</a>:</h4>
<p>:)</p>



<a name="198705664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198705664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198705664">(May 25 2020 at 22:19)</a>:</h4>
<p><span class="user-mention silent" data-user-id="211727">Jonas Schievink</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/196713710">said</a>:</p>
<blockquote>
<p>Oh, that's right. We just <code>|</code> the bits in the conflict matrix. Well that was easy.</p>
</blockquote>
<p>Turns out this is wrong, since we have to <code>&amp;</code> the bits from liveness and initializedness before adding the result to the matrix. I guess I can collect the states into a <code>Vec</code> and <code>&amp;</code> with that though.</p>



<a name="198708613"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198708613" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198708613">(May 25 2020 at 23:30)</a>:</h4>
<p>I've tried to make the dataflow traversal take linear time, but it still seems quadratic. <a href="https://github.com/rust-lang/rust/commit/f99570bd551a34f5864792ef8a685e0cff4c58d7">https://github.com/rust-lang/rust/commit/f99570bd551a34f5864792ef8a685e0cff4c58d7</a></p>
<p>Probably just a brain fart on my side though, will revisit tomorrow.</p>



<a name="198745595"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198745595" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198745595">(May 26 2020 at 10:55)</a>:</h4>
<p>Ah, adding stuff to the conflict matrix has O(n²) performance too, gotta find a better way to do that (this code was copied straight from the generator transform, so it's possible that it leaves some performance behind as well).</p>



<a name="198774744"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198774744" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198774744">(May 26 2020 at 15:02)</a>:</h4>
<blockquote>
<p>I guess I can collect the states into a Vec and &amp; with that though.</p>
</blockquote>
<p>I also don't see a better way than this. I forgot we needed the intersection of two dataflow analyses in different directions.</p>



<a name="198775745"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198775745" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198775745">(May 26 2020 at 15:07)</a>:</h4>
<p>You seem to have independently figured this out, but I think we should be specific about the  <code>n</code> when talking about the big-O notation for destination propagation going forward. AFAICT, the best we can do is <code>O(L^2 * S)</code> in time and <code>O(L^2 + S*L)</code> in memory, where <code>L</code> is the number of locals and <code>S</code> is the  number of statements in a basic block. Does this sound right? Obviously there's a very low constant factor for the <code>L</code> terms since they use bitsets.</p>



<a name="198776331"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198776331" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198776331">(May 26 2020 at 15:11)</a>:</h4>
<p>I guess it would actually be <code>O(L^2 * S * B)</code> in time for an entire function, where <code>B</code> is the number of basic blocks. And memory is <code>O(L^2 + S*L + B*L)</code>, since we need to consider the entry set for each basic block (<code>B*L</code>) as well as the intermediate buffer used to do the forward/backward intersection (<code>S*L</code>).</p>



<a name="198777562"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198777562" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198777562">(May 26 2020 at 15:18)</a>:</h4>
<p>can the algorithm be degraded to just look at a few locals in case there are too many?</p>



<a name="198777771"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198777771" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198777771">(May 26 2020 at 15:19)</a>:</h4>
<p>Or can we prefilter the locals to just look at those that are relevant at all? We have a few super local heavy tests in the perf suite, they may actually notice such a quadratic algorithm</p>



<a name="198778322"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198778322" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198778322">(May 26 2020 at 15:22)</a>:</h4>
<p><span class="user-mention" data-user-id="124288">@oli</span> We can always bail out, or fall back to my dumb version, which is linear.</p>



<a name="198778886"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198778886" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198778886">(May 26 2020 at 15:26)</a>:</h4>
<p>(I don't immediately see a subset of locals you could ignore, but perhaps <span class="user-mention" data-user-id="211727">@Jonas Schievink</span> can do better)</p>



<a name="198780483"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198780483" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198780483">(May 26 2020 at 15:36)</a>:</h4>
<p>So, if <code>m</code> out of <code>n</code> total locals are in conflict at any point, adding those <code>m</code> conflicts to the matrix takes <code>O(m²)</code> time (since it <code>|</code>s each <code>m</code>'s row in the matrix with the <code>m</code> <code>BitSet</code>). I believe this means that the <code>O(L^2 * S)</code> figure is correct, since all locals can conflict at every point in the function.</p>
<p>I think I can replace the conflict matrix with a unification table though, which should only take almost-linear time for this "add conflicts" operation, unless I missed something. I already use one in another place, so this should simplify the code too.</p>



<a name="198782278"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198782278" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198782278">(May 26 2020 at 15:48)</a>:</h4>
<p>What's a "unification table"?</p>



<a name="198782392"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198782392" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198782392">(May 26 2020 at 15:49)</a>:</h4>
<p>This thing: <a href="https://docs.rs/ena/0.14.0/ena/unify/struct.UnificationTable.html">https://docs.rs/ena/0.14.0/ena/unify/struct.UnificationTable.html</a></p>
<p>It's already used by the type inferencer</p>



<a name="198782727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198782727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198782727">(May 26 2020 at 15:51)</a>:</h4>
<p>Ah, maybe I should've just said union-find</p>



<a name="198782739"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198782739" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198782739">(May 26 2020 at 15:51)</a>:</h4>
<p>Does it require transitivity? The use of the phrase "union-find" suggests it does, but I'm not sure. I don't think you have that when detecting live-range overlaps, since "A overlaps with B" and "B overlaps with C" does not imply "A overlaps with C". Maybe you're thinking of applying it in a different way than I am, though.</p>



<a name="198782898"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198782898" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198782898">(May 26 2020 at 15:52)</a>:</h4>
<p>Ah, that is true</p>



<a name="198783240"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198783240" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198783240">(May 26 2020 at 15:55)</a>:</h4>
<p>I wouldn't worry too much the <code>L^2</code> part, since you handle 64 locals per instruction and we can always bail out for massive <code>L</code> as <span class="user-mention silent" data-user-id="124288">oli</span> mentioned. I think you already ran into a degenerative case in your earlier PR.</p>



<a name="198783482"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198783482" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198783482">(May 26 2020 at 15:56)</a>:</h4>
<p>Yeah, I'm benchmarking with said perf test (<code>tuple-stress</code>)</p>



<a name="198783540"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198783540" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198783540">(May 26 2020 at 15:56)</a>:</h4>
<p>It's true that we could just bail out when there's too many locals, just seems a bit unfortunate</p>



<a name="198783798"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198783798" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198783798">(May 26 2020 at 15:58)</a>:</h4>
<p>Frankly, if you write code that gets lowered to 100,000 MIR locals, that's on you, not on us <span aria-label="smiley" class="emoji emoji-1f603" role="img" title="smiley">:smiley:</span></p>



<a name="198783825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198783825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198783825">(May 26 2020 at 15:58)</a>:</h4>
<p>/me looks directly at <code>keccak</code></p>



<a name="198784512"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198784512" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198784512">(May 26 2020 at 16:03)</a>:</h4>
<p>FWIW, I do think there are ways of doing this that are linear (or at least quasi-linear) in time and memory, but they will be more complex than destination propagation using a conflict matrix and have higher constant factors to boot.</p>



<a name="198788021"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198788021" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198788021">(May 26 2020 at 16:30)</a>:</h4>
<p>I would agree that we should care more about getting good performance for low N, but we should also make sure to avoid exponentially increasing runtime (even if that means just switching some optimization off; eventually perhaps we can emit a warning on this "function has too many variables").</p>



<a name="198788484"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198788484" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198788484">(May 26 2020 at 16:34)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116122">simulacrum</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/198788021">said</a>:</p>
<blockquote>
<p>perhaps we can emit a warning on this "function has too many variables").</p>
</blockquote>
<p>I like this</p>



<a name="198792933"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198792933" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198792933">(May 26 2020 at 17:12)</a>:</h4>
<p>XD</p>



<a name="198792954"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198792954" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198792954">(May 26 2020 at 17:13)</a>:</h4>
<p>I dunno</p>



<a name="198793119"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198793119" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198793119">(May 26 2020 at 17:14)</a>:</h4>
<p>From what I used to hear when I was part of the Swift community, the fact that their compiler gave up sometimes and said "this expression is too complex" left a bitter taste in _everyone_ who got to see it</p>



<a name="198793153"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198793153" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198793153">(May 26 2020 at 17:14)</a>:</h4>
<p>But on the other hand that happened with fairly normal code</p>



<a name="198793201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198793201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198793201">(May 26 2020 at 17:15)</a>:</h4>
<p>If you're telling me that this would happen only with code at like, 200 local variables per function...</p>



<a name="198793216"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198793216" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198793216">(May 26 2020 at 17:15)</a>:</h4>
<p>Well, that seems actually quite fair</p>



<a name="198793225"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198793225" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198793225">(May 26 2020 at 17:15)</a>:</h4>
<p>:P</p>



<a name="198793406"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198793406" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198793406">(May 26 2020 at 17:16)</a>:</h4>
<p>Ah, wait. You're thinking of emitting a warning. Okay, my bad. Yeah, that seems pretty good :)</p>



<a name="198793490"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198793490" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198793490">(May 26 2020 at 17:17)</a>:</h4>
<p>I thought you were talking about error-ing, but that was not the case at all :)</p>



<a name="198794045"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198794045" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Wesley Wiser <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198794045">(May 26 2020 at 17:22)</a>:</h4>
<p>I'm not sure we'd even want a warning on that. It's not like the code is <em>wrong</em> it's just bloated and not necessarily going to be optimized well. </p>
<p>I think something like optimization remarks where we provide <code>// annotations</code> if requested when emitting MIR files might be more appropriate. LLVM has a much more sophisticated system that we could steal ideas from: <a href="https://llvm.org/docs/Remarks.html">https://llvm.org/docs/Remarks.html</a></p>



<a name="198794243"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198794243" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Wesley Wiser <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198794243">(May 26 2020 at 17:24)</a>:</h4>
<p>Maybe something like:</p>
<div class="codehilite"><pre><span></span><code><span class="c1">// opt-remark: [NRVO] - gave up due to too many locals!</span>
<span class="k">fn</span>  <span class="nf">bar</span><span class="p">(</span><span class="n">_1</span>: <span class="kt">u32</span><span class="p">,</span><span class="w"> </span><span class="n">_2</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="kt">u32</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="p">(</span><span class="kt">u32</span><span class="p">,</span><span class="w"> </span><span class="kt">u32</span><span class="p">,</span><span class="w"> </span><span class="kt">u32</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">debug</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">_1</span><span class="p">;</span><span class="w">                       </span><span class="c1">// in scope 0 at src/lib.rs:16:5: 16:10</span>
<span class="w">    </span><span class="n">debug</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">_2</span><span class="p">;</span><span class="w">                       </span><span class="c1">// in scope 0 at src/lib.rs:17:5: 17:6</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_0</span>: <span class="p">(</span><span class="kt">u32</span><span class="p">,</span><span class="w"> </span><span class="kt">u32</span><span class="p">,</span><span class="w"> </span><span class="kt">u32</span><span class="p">);</span><span class="w">         </span><span class="c1">// return place in scope 0 at src/lib.rs:18:6: 1</span>
<span class="w">    </span><span class="o">..</span><span class="p">.</span><span class="w"></span>
</code></pre></div>



<a name="198806830"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198806830" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198806830">(May 26 2020 at 19:04)</a>:</h4>
<p>Ohh, I kinda like that!</p>



<a name="198824040"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/198824040" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#198824040">(May 26 2020 at 21:28)</a>:</h4>
<p><a href="https://github.com/rust-lang/rust/pull/72632">https://github.com/rust-lang/rust/pull/72632</a></p>



<a name="199262382"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199262382" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199262382">(May 30 2020 at 15:38)</a>:</h4>
<p>oh nice :D</p>



<a name="199262419"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199262419" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199262419">(May 30 2020 at 15:39)</a>:</h4>
<p><span class="user-mention" data-user-id="211727">@Jonas Schievink</span> if you want to get some extra checking of whether the MIR still makes sense, you could try</p>
<div class="codehilite"><pre><span></span><code>MIRI_TEST_FLAGS=&quot;-Z mir-opt-level=3&quot; ./x.py test --stage 0 src/tools/miri
</code></pre></div>



<a name="199262593"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199262593" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199262593">(May 30 2020 at 15:43)</a>:</h4>
<p>Thanks, no failures with that though</p>



<a name="199262684"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199262684" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199262684">(May 30 2020 at 15:45)</a>:</h4>
<p>I've been trying to extend the MIR validation pass to check the MIR against the live and initialized locals from dataflow, and it reports a lot of errors. I'll try to narrow those down next.</p>



<a name="199270541"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199270541" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199270541">(May 30 2020 at 18:50)</a>:</h4>
<p>Whoa, just noticed this immense amount of test failures <a href="https://github.com/rust-lang/rust/pull/72635/checks?check_run_id=711136389">https://github.com/rust-lang/rust/pull/72635/checks?check_run_id=711136389</a></p>
<p>I can't reproduce any of that locally</p>



<a name="199278455"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199278455" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199278455">(May 30 2020 at 22:15)</a>:</h4>
<p>Great, my <code>InstCombine</code> changes break dest-prop and <code>MaybeInitializedLocals</code> <a href="https://github.com/rust-lang/rust/issues/72797">#72797</a></p>
<p>Not entirely sure what to do, but I guess we can revert the <code>Operand::Move</code> change for now?</p>



<a name="199282478"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199282478" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199282478">(May 31 2020 at 00:21)</a>:</h4>
<p>Found another issue, this time with <code>SimplifyArmIdentity</code>: <a href="https://github.com/rust-lang/rust/issues/72800">#72800</a></p>
<p>(that MIR validation pass I added is really starting to pay off!)</p>



<a name="199294294"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199294294" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199294294">(May 31 2020 at 06:50)</a>:</h4>
<p><span class="user-mention" data-user-id="211727">@Jonas Schievink</span> I cannot thank you enough for that pass. Anything that helps to ensure that our opts are, at the end of the day, sound, is imo incredibly important.</p>



<a name="199294306"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199294306" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199294306">(May 31 2020 at 06:51)</a>:</h4>
<p>Although MIR validation isn't fool-proof (you could make a transform that changes program behavior and still generates valid MIR), I still think it's a great tool</p>



<a name="199294350"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199294350" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199294350">(May 31 2020 at 06:53)</a>:</h4>
<p>What I eventually would love to have is some sort of proof that the opts are all valid transformations over a MIR program. But that feels more like end-game stuff</p>



<a name="199429438"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199429438" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199429438">(Jun 01 2020 at 22:01)</a>:</h4>
<p>Ah, just found this gem, this isn't sound of course:</p>
<div class="codehilite"><pre><span></span><code><span class="gd">-        _44 = const std::option::Option::&lt;ExpandError&gt;::or(move _45, move _46) -&gt; [return: bb20, unwind: bb49]; // scope 12 at crates/ra_mbe/src/mbe_expander/transcriber.rs:97:23: 97:32</span>
<span class="gi">+        _45 = const std::option::Option::&lt;ExpandError&gt;::or(move _45, move _46) -&gt; [return: bb20, unwind: bb49]; // scope 12 at crates/ra_mbe/src/mbe_expander/transcriber.rs:97:23: 97:32</span>
</code></pre></div>



<a name="199436313"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199436313" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199436313">(Jun 01 2020 at 23:37)</a>:</h4>
<p>Looks like we can do a lot more "must not overlap" validation in the MIR validator, this would have easily caught this case</p>



<a name="199436360"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199436360" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199436360">(Jun 01 2020 at 23:38)</a>:</h4>
<p>Luckily the rust-analyzer test suite started crashing, or I would have to bisect the entire rustc</p>



<a name="199541773"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/199541773" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#199541773">(Jun 02 2020 at 19:32)</a>:</h4>
<p>Okay, that fixed the rust-analyzer crash, but not the rustc miscompilation. In fact, there is now an additional spurious error emitted :(</p>



<a name="201471759"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201471759" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201471759">(Jun 20 2020 at 10:23)</a>:</h4>
<p><span class="user-mention" data-user-id="211727">@Jonas Schievink</span>  so regarding the overlap check, IMO before we add lots of static approximations of what the actual allowed and disallowed overlap behavior of assignments is, and certainly before we have any optimizations that rely on it, we should figure out the dynamic MIR semantics regarding overlap: <a href="https://github.com/rust-lang/rust/issues/68364">https://github.com/rust-lang/rust/issues/68364</a></p>



<a name="201471810"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201471810" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201471810">(Jun 20 2020 at 10:24)</a>:</h4>
<p>once we know those, we can determine if a static check is correct by seeing if it conservatively approximates the true dynamic overlap requirement</p>



<a name="201473862"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201473862" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201473862">(Jun 20 2020 at 11:27)</a>:</h4>
<p>Makes sense to me, but I don't know what's required to settle that. Your comment <a href="https://github.com/rust-lang/rust/issues/68364#issuecomment-614862820">https://github.com/rust-lang/rust/issues/68364#issuecomment-614862820</a> makes it sound like there's a good solution already.</p>



<a name="201474476"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201474476" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201474476">(Jun 20 2020 at 11:46)</a>:</h4>
<p>there's a reasonable candidate that is neither implemented nor ratified by the lang team</p>



<a name="201550637"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201550637" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201550637">(Jun 21 2020 at 20:04)</a>:</h4>
<p>Is that candidate described somewhere <span class="user-mention" data-user-id="120791">@RalfJ</span>? :3</p>



<a name="201556443"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201556443" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201556443">(Jun 21 2020 at 22:51)</a>:</h4>
<p><span class="user-mention" data-user-id="212698">@Félix Fischer</span> yeah it's in jonas' message above: <a href="https://github.com/rust-lang/rust/issues/68364#issuecomment-614862820">https://github.com/rust-lang/rust/issues/68364#issuecomment-614862820</a></p>



<a name="201558704"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201558704" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201558704">(Jun 22 2020 at 00:01)</a>:</h4>
<p>Thank you <span class="user-mention" data-user-id="120791">@RalfJ</span> <span aria-label="two hearts" class="emoji emoji-1f495" role="img" title="two hearts">:two_hearts:</span></p>



<a name="201558821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201558821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201558821">(Jun 22 2020 at 00:04)</a>:</h4>
<p>While we're at it... is there a guide on MIR? Like...</p>



<a name="201558824"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201558824" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201558824">(Jun 22 2020 at 00:04)</a>:</h4>
<p>MIR semantics</p>



<a name="201558825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201558825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201558825">(Jun 22 2020 at 00:04)</a>:</h4>
<p>And</p>



<a name="201558832"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201558832" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201558832">(Jun 22 2020 at 00:04)</a>:</h4>
<p>What the Rust~&gt;MIR transform does</p>



<a name="201558851"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201558851" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201558851">(Jun 22 2020 at 00:05)</a>:</h4>
<p>Because while reading these documents I feel like I don't quite understand what's going on, like, I'm missing a lot of context</p>



<a name="201559544"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201559544" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201559544">(Jun 22 2020 at 00:28)</a>:</h4>
<p>I only have superficial understanding of how MIR is built, but the docs at <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/build/index.html">https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/build/index.html</a> have been helpful for me, in case you haven't read them yet</p>



<a name="201574251"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201574251" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201574251">(Jun 22 2020 at 07:22)</a>:</h4>
<p><span class="user-mention silent" data-user-id="212698">Félix Fischer</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/201558824">said</a>:</p>
<blockquote>
<p>MIR semantics</p>
</blockquote>
<p>this has been on my todo list since forever^^</p>



<a name="201574266"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201574266" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201574266">(Jun 22 2020 at 07:23)</a>:</h4>
<p>It's something I hope <a href="https://github.com/rust-lang/unsafe-code-guidelines/">the UCG</a> will get to eventually</p>



<a name="201574286"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201574286" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201574286">(Jun 22 2020 at 07:23)</a>:</h4>
<p>so far we just have some bits an pieces, and none of that is normative or ratified:<br>
<a href="https://github.com/rust-lang/unsafe-code-guidelines/tree/master/wip">https://github.com/rust-lang/unsafe-code-guidelines/tree/master/wip</a></p>



<a name="201668665"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201668665" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201668665">(Jun 22 2020 at 22:25)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/201471759">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="211727">Jonas Schievink</span>  so regarding the overlap check, IMO before we add lots of static approximations of what the actual allowed and disallowed overlap behavior of assignments is, and certainly before we have any optimizations that rely on it, we should figure out the dynamic MIR semantics regarding overlap: <a href="https://github.com/rust-lang/rust/issues/68364">https://github.com/rust-lang/rust/issues/68364</a></p>
</blockquote>
<p>Circling back to this – would it really be such a bad idea to have the validator check for cases that codegen already assumes <em>today</em> won't alias? I'm fairly sure this would have caught almost every recent destination propagation miscompile I had to debug, and if we figure out later that codegen is doing something wrong then we can always relax the validator too. (these assumptions wouldn't be <em>exploited</em> by optimization passes either, in fact I need to do the exact opposite right now)</p>



<a name="201696382"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201696382" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201696382">(Jun 23 2020 at 07:50)</a>:</h4>
<p>it is probably a good idea to already check statically for things that we anyway rely on. I am just worried that we'll stop there, when I think we do need a precise dynamic description of what happens if we want to actually understand things.</p>



<a name="201696404"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201696404" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201696404">(Jun 23 2020 at 07:50)</a>:</h4>
<blockquote>
<p>(these assumptions wouldn't be exploited by optimization passes either, in fact I need to do the exact opposite right now)</p>
</blockquote>
<p>interesting, I thought they could be useful but maybe we don't have such optimizations yes?</p>



<a name="201705352"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201705352" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201705352">(Jun 23 2020 at 09:35)</a>:</h4>
<p>In a way, codegen relying on this could count as an optimization. I don't think we have anything beyond that at the moment.</p>



<a name="201752680"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201752680" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201752680">(Jun 23 2020 at 16:56)</a>:</h4>
<p><span class="user-mention silent" data-user-id="211727">Jonas Schievink</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations/near/201705352">said</a>:</p>
<blockquote>
<p>In a way, codegen relying on this could count as an optimization.</p>
</blockquote>
<p>fair</p>



<a name="201906903"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201906903" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201906903">(Jun 24 2020 at 21:35)</a>:</h4>
<p><a href="https://github.com/rust-lang/rust/issues/72632">#72632</a> should now be ready for review</p>



<a name="201921629"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/201921629" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Félix Fischer <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#201921629">(Jun 25 2020 at 00:51)</a>:</h4>
<p>Holy crap, good job!</p>



<a name="210584033"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/210584033" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#210584033">(Sep 18 2020 at 23:04)</a>:</h4>
<p><a href="https://github.com/rust-lang/rust/issues/72632">#72632</a> is now waiting on bors.</p>



<a name="210584234"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Status%20of%20NRVO-like%20optimizations/near/210584234" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Status.20of.20NRVO-like.20optimizations.html#210584234">(Sep 18 2020 at 23:07)</a>:</h4>
<p>And because I can't help myself, I wrote another copy propagation pass: <a href="https://github.com/rust-lang/rust/issues/76723">#76723</a></p>
<p>This one propagates forwards, and only within individual basic blocks, but runs so fast that it doesn't regress compiler performance measurably. The result is faster incremental builds due to less MIR being stored in the cache, and faster CTFE. The pass is also pretty small and should be relatively easy to understand.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>